/**
 * @file xdisk.h
 * @author zhao yijiing
 * @brief  disk层
 * @version 0.1
 * @date 2022-11-03
 *
 * @copyright Copyright (c) 2022
 *
 */
#ifndef __XDISK_H
#define __XDISK_H

#include "xtypes.h"

#define MBR_PRIMARY_PART_NR 4 // 分区表项数 固定4项
struct _xdisk;

// 文件系统类型枚举
typedef enum _xfs_type
{
    FS_NOT_VALID = 0x00,     // 无效类型
    FS_FAT32 = 0x01,         // FAT32
    FS_EXTEND = 0x05,        // 扩展分区
    FS_WIN95_FAT32_0 = 0x0B, // FAT32
    FS_WIN95_FAT32_1 = 0x0C, // FAT32
} xfs_type_t;

// 磁盘驱动接口
typedef struct _xdisk_driver
{
    xfat_err_t (*open)(struct _xdisk *disk, void *init_data);
    xfat_err_t (*close)(struct _xdisk *disk);
    xfat_err_t (*write_sector)(struct _xdisk *disk, uint8_t *buf, uint32_t start_sector, uint32_t count);
    xfat_err_t (*read_sector)(struct _xdisk *disk, uint8_t *buf, uint32_t start_sector, uint32_t count);
} xdisk_driver_t;

// 存储设备类型
typedef struct _xdisk
{
    const char *name;       // 设备名
    uint32_t sector_size;   // 块大小
    uint32_t totle_sector;  // 总块数
    xdisk_driver_t *driver; // 驱动接口
    void *data;             // 自定义参数 可以用来记录打开的文件
} xdisk_t;

#pragma pack(1)
// 分区表项
typedef struct _mbr_part
{
    uint8_t boot_active;          // 分区活动标志
    uint8_t start_header;         // 起始header
    uint16_t start_sector : 6;    // 起始扇区
    uint16_t start_cylinder : 10; // 起始磁道
    uint8_t system_id;            // 文件系统类型
    uint8_t end_header;           // 结束header
    uint16_t end_sector : 6;      // 结束扇区
    uint16_t end_cylinder : 10;   // 结束磁道
    uint32_t relative_sector;     // 相对于该驱动器开始的相对扇区数
    uint32_t total_sector;        // 总的扇区数
} mbr_part_t;

// MBR区域描述符
typedef struct _mbr
{
    uint8_t code[446];                         // 446Byte代码
    mbr_part_t part_info[MBR_PRIMARY_PART_NR]; // 64Byte分区表
    uint8_t boot_sig[2];                       // 引导标志
} mbr_t;
#pragma pack()

// 存储设备分区类型
typedef struct _xdisk_part
{
    uint32_t start_sector; // 起始扇区 相对于物理磁盘
    uint32_t total_sector; // 分区总扇区数
    xfs_type_t type;       // 分区文件系统类型
    xdisk_t *disk;         // 对应的存储设备
} xdisk_part_t;

// 驱动接口
xfat_err_t xdisk_open(xdisk_t *disk, const char *name, xdisk_driver_t *driver, void *init_data);
xfat_err_t xdisk_close(xdisk_t *disk);
xfat_err_t xdisk_write_sector(xdisk_t *disk, uint8_t *buf, uint32_t start_sector, uint32_t count);
xfat_err_t xdisk_read_sector(xdisk_t *disk, uint8_t *buf, uint32_t start_sector, uint32_t count);
xfat_err_t xdisk_get_part_count(xdisk_t *disk, uint32_t *count);
xfat_err_t xdisk_get_part(xdisk_t *disk, xdisk_part_t *xdisk_part, int part_no);

#endif /* __XDISK_H */
